package com.sunwayworld.basemodule.common.eptstorage.file.excelread.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.context.csv.DefaultCsvReadContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.sunwayworld.basemodule.common.eptstorage.file.excelread.bean.LimsSheetReadconfigBean;
import com.sunwayworld.basemodule.common.eptstorage.file.excelread.bean.LimsSheetTitleConfigBean;
import com.sunwayworld.framework.utils.ObjectUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @auther zhangs
 */
public class ExcelModelListener extends AnalysisEventListener<Map<Integer,String>> {

    private static final Logger logger = LogManager.getLogger(ExcelModelListener.class);

    private List<LimsSheetReadconfigBean> sheetconfigBeans;
    private List<LimsSheetTitleConfigBean> titleConfigBeans;
    private Map<String,List<LimsSheetTitleConfigBean>> sheetTitles = new HashMap<>();
    private List<SheetData> sheetDatas;
    private long rowIndex = 0;

    public ExcelModelListener(List<LimsSheetReadconfigBean> sheetconfigBeans, List<LimsSheetTitleConfigBean> titleConfigBeans,List<SheetData> sheetDatas) {
        this.sheetconfigBeans = sheetconfigBeans;
        this.titleConfigBeans = titleConfigBeans;
        this.sheetDatas = sheetDatas;
        for (LimsSheetReadconfigBean sheetconfigBean : sheetconfigBeans) {
            SheetData sheetData = new SheetData();
            sheetData.setSheetName(sheetconfigBean.getSheetName());
            sheetData.setMongoDocument(sheetconfigBean.getMongoDocument());
            if(ObjectUtils.isEmpty(sheetconfigBean.getMongoDocument())){
                sheetData.setMongoDocument(sheetconfigBean.getExt$Item("excelmongodbdoc"));
            }
            sheetData.setRowDataList(new ArrayList<>());
            sheetDatas.add(sheetData);

            sheetTitles.put(sheetconfigBean.getSheetName(),getTitleOfSheet(sheetconfigBean));
        }
    }

    private List<LimsSheetTitleConfigBean> getTitleOfSheet(LimsSheetReadconfigBean sheetReadconfigBean){
        return titleConfigBeans.stream().filter(f->f.getSheetId().longValue()==sheetReadconfigBean.getId().longValue()).collect(Collectors.toList());
    }
    private LimsSheetReadconfigBean getSheetConfigByName(String sheetName,Integer sheetNo){
        Optional<LimsSheetReadconfigBean> first = sheetconfigBeans.stream().filter(f->{
            String findSheetByName = f.getFindSheetByName();
            if("1".equals(findSheetByName)){
                //如果是正则匹配，则按正则匹配
                if("1".equals(f.getRegexMatchName())){
                    return Pattern.compile(f.getSheetName()).matcher(sheetName).matches();
                }else{
                    return f.getSheetName().equals(sheetName);
                }
            }else{
                return f.getSheetNo()==sheetNo;
            }
        }).findFirst();
        return first.isPresent()?first.get():null;
    }

    @Override
    public void invoke(Map<Integer,String> t, AnalysisContext analysisContext) {
        rowIndex++;
        String sheetName = analysisContext.readSheetHolder().getSheetName(); //实际sheet名字
        Integer sheetNo = analysisContext.readSheetHolder().getSheetNo();
        LimsSheetReadconfigBean sheetReadconfigBean;
        if(analysisContext instanceof DefaultCsvReadContext){
            //csv解析,csv只有一个sheet
            sheetReadconfigBean = sheetconfigBeans.get(0);
            sheetName = sheetReadconfigBean.getSheetName();
        }else{
            sheetReadconfigBean = getSheetConfigByName(sheetName,sheetNo); //一个sheetReadconfigBean可能对应多个实际sheet
        }
        if(sheetReadconfigBean==null){
            return;
        }

        if(rowIndex==sheetReadconfigBean.getHeadRowNumber()){
            List<LimsSheetTitleConfigBean> titleConfigBeans = sheetTitles.get(sheetReadconfigBean.getSheetName());
            String finalSheetName = sheetName;
            SheetData sheetData = sheetDatas.stream().filter(f -> {
                String findSheetByName = sheetReadconfigBean.getFindSheetByName();
                if("1".equals(findSheetByName)){
                    if("1".equals(sheetReadconfigBean.getRegexMatchName())){
                        return Pattern.compile(f.getSheetName()).matcher(finalSheetName).matches();
                    }else{
                        return f.getSheetName().equals(finalSheetName);
                    }
                }else{
                    return sheetReadconfigBean.getSheetNo()==sheetNo;
                }
            }).findFirst().get();
            Map<String, String> titleMap = new LinkedHashMap<>(); //匹配到colIndex对应的title,en_title
            for (LimsSheetTitleConfigBean titleConfigBean : titleConfigBeans) {
                String colIndex = "-1";
                Set<Map.Entry<Integer, String>> entries = t.entrySet();
                for(Map.Entry<Integer, String> en : entries){
                    Integer col = en.getKey();
                    String value = en.getValue();
                    if(value!=null && value.equals(titleConfigBean.getTitle())){
                        colIndex = col+"";
                    }
                }
                if(!"-1".equals(colIndex)){
                    titleMap.put(colIndex,titleConfigBean.getTitle_En());
                }
            }
            sheetData.setTitleFieldMap(titleMap);
        }
        if(rowIndex>sheetReadconfigBean.getHeadRowNumber().intValue()){
            String finalSheetName1 = sheetName;
            SheetData sheetData = sheetDatas.stream().filter(f -> {
                String findSheetByName = sheetReadconfigBean.getFindSheetByName();
                if("1".equals(findSheetByName)){
                    if("1".equals(sheetReadconfigBean.getRegexMatchName())){
                        return Pattern.compile(f.getSheetName()).matcher(finalSheetName1).matches();
                    }else{
                        return f.getSheetName().equals(finalSheetName1);
                    }
                }else{
                    return sheetReadconfigBean.getSheetNo()==sheetNo;
                }
            }).findFirst().get();
            Map<String, String> titleFieldMap = sheetData.getTitleFieldMap();
            if(titleFieldMap!=null && !titleFieldMap.isEmpty()){
                ExcelRowData rowData = new ExcelRowData();
                rowData.setSheetName(sheetReadconfigBean.getSheetName());
                rowData.setValues(convertValue(t,titleFieldMap));
                sheetData.getRowDataList().add(rowData);
            }
        }
    }

    private LinkedHashMap<String, Object> convertValue(Map<Integer, String> t, Map<String, String> titleFieldMap) {
        LinkedHashMap<String,Object> row = new LinkedHashMap<>();
        titleFieldMap.forEach((colIndex,field)->{
            String value = t.get(Integer.parseInt(colIndex));
            row.put(field,value);
        });
        return row;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        rowIndex = 0; //一个sheet解析完毕
        String sheetName;
        if(analysisContext instanceof DefaultCsvReadContext){
            //csv解析,csv只有一个sheet
            sheetName = sheetconfigBeans.get(0).getSheetName();
        }else{
            sheetName = analysisContext.readSheetHolder().getSheetName();
        }
        logger.info("解析完毕。。。。"+sheetName);
    }

    private ExcelRowData convertToExcelRowData(Map<Integer, String> t,String sheetName){
        logger.info(t);
        ExcelRowData  rowData = null;
        if(t!=null && !t.isEmpty()){
            rowData  = new ExcelRowData();
            rowData.setSheetName(sheetName);
            LinkedHashMap<String, Object> values = new LinkedHashMap<>();
            t.forEach((colIndex,value)->{

            });
            rowData.setValues(values);
        }
        return rowData;
    }

}
